﻿#ifndef JCPRINTERAPI_H_H_H_H
#define JCPRINTERAPI_H_H_H_H

#include <iostream>
#include <windows.h>
#include "define.h"

namespace jcPrinterApi
{
	/**
	 * 初始化字体路径，可默认空
	 * @param[in] font 字体文件夹
	 * @return 初始化成功返回true
	 */
	typedef bool  (*INITSDK)(char* fontDir);

	typedef bool (*UNINITSDK)();

	/**
	 * 获取打印错误
	 * @return 错误码
	 *  | 错误码                         | 说明                    |
		| ----------------------------- | ------------------------|
		| E_NO_ERROR = 0                | 无错误                   |
		| E_BOX_OPENED = 1              | 盒盖打开                 |
		| E_NO_PAPER = 2                | 缺纸                     |
		| E_LOW_VOLTAGE = 3             | 电量不足                 |
		| E_BATTERY_UNNORMAL = 4        | 电池异常                 |
		| E_HANDLE_STOP = 5             | 手动停止                 |
		| E_DATA_ERROR = 6              | 数据错误                 |
		| E_HIGH_TEMPRATURE = 7         | 温度过高                 |
		| E_PAPER_OUT = 8               | 走纸异常                 |
		| E_IS_PRINTING = 9             | 正在打印                 |
		| E_NO_PRINTHEAD_DETECT = 10    | 未检测到打印头           |
		| E_TEMPRATURE_LOW = 11         | 环境温度过低             |
		| E_PRINTHEAD_FLEXIBLE = 12     | 打印头松动               |
		| E_NO_CARBON_BANDS = 13        | 未检测到碳带             |
		| E_NO_MATCH_CARBON_BANDS = 14  | 耗材不匹配               |
		| E_USED_CARBON_BANDS = 15      | 碳带用完                 |
		| E_PARPER_UNNORMAL = 16        | 纸张类型不支持           |
		| E_SET_PARPER_FAIL = 17        | 设置纸张类型失败         |
		| E_SET_PRINT_MODE_FAIL = 18    | 设置打印模式失败         |
		| E_SET_DENSITY_FAIL = 19       | 设置浓度失败             |
		| E_WRITE_RFID_FAIL = 20        | 写入rfid失败             |
		| E_MARGIN_ERROR = 21           | 边距参数错误             |
		| E_TIMEOUT = 22                | 超时错误                 |
		| E_DISCONNECT = 23             | 断开连接                 |
		| E_DRAWBOARD_ERROR = 24        | 画板参数设置错误         |
		| E_ORIENTATION_ERROR = 25      | 旋转角度参数错误         |
		| E_JSON_ERROR = 26             | JSON参数错误             |
		| E_PAPER_OUT_S = 27            | 出纸异常（关闭上盖检测）（已废弃） |
		| E_CHECK_PAPER = 28            | 检查纸张类型             |
		| E_PRINT_MODE = 29             | 碳带与打印模式不匹配     |
		| E_SET_DENSITY_NO_SUPPORT = 30 | 设置浓度不支持           |
		| E_PRINT_MODE_NO_SUPPORT  = 31 | 打印模式不支持           |
		| E_UNKNOW_ERROR = 255          | 未定义错误               |
	 */
	typedef int (*GETPRINTLASTERROR)();

	/********************************************************打印接口*********************************************************************/
	/**
	 * 查找打印机
	 * 以json形式返回{打印机名称，端口}
	 * Example： "{"S6_0011223344":"4"}"
	 * @return 返回数据的指针 char *
	 */
	typedef char* (*GETALLPRINTERS)();

	/**
	 * 连接打印机
	 * @param[in] printerName 打印机名称（使用 `getAllPrinters `获取的打印机名称）
	 * @param[in] port 打印机端口, `getAllPrinters`获取的打印机端口
	 * @return 连接成功返回true
	 */
	typedef bool (*SELECTPRINTER)(char* printerName, int port);

	/**
	 * 断开连接
	 * @return 操作成功返回true
	 */
	typedef bool (*DISCONNECTPRINTER)();

	/**
	 * 设置打印信息
	 * @param[in] printLabelType 纸张类型：
	 *                           1-间隙纸，2-⿊标纸，3-连续纸，4-过孔纸，5-透明纸
	 * @param[in] printDensity 浓度，浓度范围1-5
	 * @param[in] printMode 打印类型：
	 *                      1-热敏
	 *                      2-热转印
	 * @param[in] printCount 打印份数
	 * @return 设置成功返回true
	 */
	typedef bool (*STARJOB)(int printLabelType, int printDensity, int printMode, int printCount);

	typedef bool (*STARTJOB_NEW)(StartJobParameter param);

	/**
	 * 提交打印任务
	 * 使用绘制接口绘制打印数据需要调用此接口打印数据
	 */
	typedef bool (*COMMITJOB)();

	/**
	 * 图片打印
	 * @param printData 图片数据
	 * @param dataLenght 图片数据长度
	 * @param verticalShift 水平偏移
	 * @param horizontalShift 垂直偏移
	 * @param threshold 二值化临界点（默认使用127）
	 * @return
	 */
	typedef bool (*PICTUREPRINT)(char* printData, size_t dataLenght, int verticalShift, int horizontalShift, int threshold);

	/**
	 * 结束打印
	 */
	typedef bool (*ENDJOB)();

	/**
	* 测试USB设备连接状态
	*/
	typedef bool (*ISCONNECTED)();

	/**
	 * 查找Wifi打印机
	 * 以json形式返回{打印机名称，端口}
	 * Example： "{"S6_0011223344":"4"}"
	 * @return 返回数据的指针 char *
	 */
	typedef char* (*SCANWIFIPRINTER)();

	/**
	 * 连接Wifi打印机
	 * @param[in] printerName 打印机名称（使用 `scanWifiPrinter `获取的打印机名称）
	 * @param[out] port 打印机端口, `scanWifiPrinter`获取的打印机端口(以ip地址为基础模拟端口号)
	 * @return 连接成功返回true
	 */
	typedef bool (*CONNECTWIFIPRINTER)(char* printerName, int port);

	/**
	* 配置Wifi网络
	* @param wifiName wifi热点名称
	* @param wifiPassword wifi热点密码
	* @return true为成功，false为失败
	*/
	typedef bool (*CONFIGURATIONWIFI)(char* wifiName, char* wifiPassword);

	/*
   * 获取标签信息
   * @param gapHeightPixel 缝隙高度(像素)
   * @param gapHeight 缝隙高度(毫米)
   * @param totalHeightPixel 标签高度(包含缝隙高度)(像素)
   * @param totalHeight 标签高度(包含缝隙高度)(毫米)
   * @param paperType 纸张类型
   * @param paperWidthPixel 标签宽度(像素)
   * @param paperWidth 标签宽度(毫米)
   * @param direction 标签尾巴方向 1-上 2-下 3-左 4-右
   * @param tailLengthPixel 标签尾巴长度(像素)
   * @param tailLength 标签尾巴长度(毫米)
   */
	typedef bool(*GETPAPERINFO)(int& gapHeightPixel, float& gapHeight, int& totalHeightPixel, float& totalHeight, int& paperType,
		int& paperWidthPixel, float& paperWidth, int& direction, int& tailLengthPixel, float& tailLength);

	/********************************************************绘制接口***********************************************************************/
	/*
	 * 初始化画板
	 * @param width 画板宽度，单位mm
	 * @param height 画板高度，单位mm
	 * @param rotate 旋转角度，仅支持0,90,180,270
	 * @param font 字体,默认使用 "ZT001.ttf"
	 * @param verticalShift 垂直偏移
	 * @param horizontalShift 水平偏移
	 * @return 初始化成功返回 true
	 */
	typedef bool (*INITDRAWINGBOARD)(float width, float height, int rotate, const char* font, int verticalShift, int HorizontalShift);

	/*
	 * 绘制文本
	 * @param x 水平坐标
	 * @param y 垂直坐标
	 * @param width 宽度， 单位mm
	 * @param height 高度，单位mm
	 * @param value 绘制的文本（UTF8）
	 * @param fontFamily 字体，默认使用 "ZT001.ttf"
	 * @param fontSize 字体大小
	 * @param textAlignHorizonral 水平对齐方式，0:左对齐 1:居中对齐 2:右对齐
	 * @param textAlignVertical 垂直对齐方式，0:顶对齐 1:垂直居中 2:底对齐
	 * @param lineMode 行模式，默认2
	 *                  1:宽高固定，内容大小自适应（字号/字符间距/行间距 按比例缩放）
	 *                  2:宽度固定，高度自适应
	 *                  3:宽高固定，超出内容后面加...
	 *                  4:宽高固定,超出内容直裁切
	 * @param letterSpacing 字间距，单位mm
	 * @param lineSpacing 行间距，单位mm
	 * @param fontStyle 字体风格（加粗、斜体、下划线），数据格式[斜体，加粗，下划线，保留]
	 * @return
	 */
	typedef bool (*DRAWLABLETEXT)(float x, float y, float width, float height, const char* value, const char* fontFamily, float fontSize, int rotate,
		int textAlignHorizonral, int textAlignVertical, int lineMode, float letterSpacing, float lineSpacing, bool fontStyle[4]);

	/*
	 * 绘制一维码
	 * @param x 水平坐标
	 * @param y 垂直坐标
	 * @param width 宽，单位mm
	 * @param height 高，单位mm
	 * @param rotate: 旋转角度，仅支持0,90,180,270
	 * @param value 文本内容（UTF8）
	 * @param fontSize 字号
	 * @param codeType 条码类型：
	 *               20:CODE12821:UPC-A
	 *               22:UPC-E
	 *               23:EAN8
	 *               24:EAN13
	 *               25:CODE93
	 *               26:CODE39
	 *               27:CODEBAR
	 *               28:ITF25
	 * @param textHeight 文本高度
	 * @param textPosition 文本位置（上、下、无）
	 *                      0：下方
	 *                      1：上方，
	 *                      2：不显示
	 */
	typedef bool (*DRAWLABLEBARCODE)(float x, float y, float width, float height, int codeType, const char* value, float fontSize,
		int rotate, float textHeight, int textPosition);

	/*
	 * 绘制二维码
	 * @param x 起始点左上角水平方向位置
	 * @param y 起始点左上角垂直方向位置
	 * @param width 宽
	 * @param height 高
	 * @param value 文本内容（UTF8）
	 * @param codeType 条码类型
	 *                  31:QR_CODE
	 *                  32:PDF417
	 *                  33:DATA_MATRIX
	 *                  34:AZTEC
	 * @param rotate: 旋转角度，0、90、180、270
	 */
	typedef bool (*DRAWLABLEQRCODE)(float  x, float y, float width, float height, const char* value, int codeType, int rotate);

	/*
	 * 绘制带logo二维码
	 * @param x 起始点左上角水平方向位置
	 * @param y 起始点左上角垂直方向位置
	 * @param width 宽
	 * @param height 高
	 * @param value 文本内容（UTF8）
	 * @param codeType 条码类型
	 *                  31:QR_CODE
	 *                  32:PDF417
	 *                  33:DATA_MATRIX
	 *                  34:AZTEC
	 * @param rotate: 旋转角度，0、90、180、270
	 * @param correctLevel: 修正等级
	 * @param logoBase64：logo图片Base64
	 * @param logoPosition：logo的位置
	 * @param logoScale：logo压缩
	 */
	typedef bool (*DRAWLABLEQRCODEWITHIMAGE)(float  x, float y, float width, float height, const char* value, int codeType, int rotate, int correctLevel, char* logoBase64, int logoPosition,//logo位置
		float logoScale);

	/*
	 * 绘制线条
	 * @param x 起始点左上角水平方向位置
	 * @param y 起始点左上角垂直方向位置
	 * @param width 宽
	 * @param height 高
	 * @param rotate: 旋转角度，0、90、180、270
	 * @param lineType 线类型（虚线、实线）
	 * @param dashwidth 数据格式[实线段长度，空线段长度]
	 */
	typedef bool (*DRAWLABLELINE)(float x, float y, float width, float height, int rotate, int lineType, float dashwidth[2]);

	/*
	 * 绘制图形
	 * @param x 起始点左上角水平方向位置
	 * @param y 起始点左上角垂直方向位置
	 * @param width 宽
	 * @param height 高
	 * @param graphType 图形类型
	 *                  1:圆
	 *                  2:椭圆
	 *                  3:矩形
	 * @param rotate 旋转角度, 0、90、180、270
	 * @param cornerRadius 圆角半径
	 * @param lineWidth 线宽
	 * @param lineType 线类型,
	 *                  1:实线
	 *                  2:虚线类型
	 * @param dashwidth 数据格式[实线段长度，空线段长度]
	 */
	typedef bool (*DRAWLABLEGRAPH)(float x, float y, float width, float height, int graphType, int rotate,
		float cornerRadius, float lineWidth, int lineType, float dashwidth[2]);

	/*
	 * 绘制图片
	 * @param imageData 图片数据
	 * @param x 起始点左上角水平方向位置
	 * @param y 起始点左上角垂直方向位置
	 * @param width 宽
	 * @param height 高
	 * @param imageProcessingType 图像处理方式（默认使用0）
	 *  							1:阈值法
	 *								2:渐变
	 * @param imageProcessingValue 图像处理阈值（默认使用0）
	 */
	typedef bool (*DRAWLABLEIMAGE)(const char* imageData, float x, float y, float width, float height, int rotate,
		int imageProcessingType, float imageProcessingValue);

	/*
	 * 生成预览图
	 * @param displayMultiple 显示器倍率（如8.0f）
	 * @return 图像数据
	 */
	typedef char* (*GENERATEPRINTPREVIEWIMAGE)(float displayMultiple);

	/*
	 * 释放缓存buffer
	 */
	typedef void(*FREEBUFFER)(char* ptr);


	HINSTANCE hDLL = NULL;
	INITSDK    initSdk;
	UNINITSDK unInitSdk;
	GETPRINTLASTERROR   getPrintLastError;
	//画板
	INITDRAWINGBOARD    InitDrawingBoard;
	DRAWLABLETEXT       DrawLableText;
	DRAWLABLEBARCODE    DrawLableBarCode;
	DRAWLABLEQRCODE     DrawLableQrCode;
	DRAWLABLELINE       DrawLableLine;
	DRAWLABLEGRAPH      DrawLableGraph;
	DRAWLABLEIMAGE      DrawLableImage;
	FREEBUFFER	        FreeBuffer;
	GENERATEPRINTPREVIEWIMAGE GeneratePrintPreviewImage;
	//打印流程
	SELECTPRINTER       selectPrinter;
	DISCONNECTPRINTER   disconnectPrinter;
	GETALLPRINTERS      getAllPrinters;
	STARJOB             startJob;
	STARTJOB_NEW        startJob_New;
	COMMITJOB           commitJob;
	PICTUREPRINT        picturePrint;
	ENDJOB              endJob;
	ISCONNECTED         isConnected;
	SCANWIFIPRINTER     scanWifiPrinter;
	CONNECTWIFIPRINTER  connectWifiPrinter;
	CONFIGURATIONWIFI   configurationWifi;
	GETPAPERINFO        getPaperInfo;
	DRAWLABLEQRCODEWITHIMAGE DrawLableQrCodeWithImage;

	bool loadPrinterApiDll()
	{
		hDLL = LoadLibrary("jcPrinterApi.dll");
		DWORD error_id = GetLastError();

		if (hDLL != NULL)
		{
			getAllPrinters = (GETALLPRINTERS)GetProcAddress(hDLL, "getAllPrinters");
			if (!getAllPrinters)
			{
				std::cout << "get getAllPrinters API error!" << std::endl;
				return false;
			}

			InitDrawingBoard = (INITDRAWINGBOARD)GetProcAddress(hDLL, "InitDrawingBoard");
			if (!InitDrawingBoard)
			{
				std::cout << "get InitDrawingBoard API error!" << std::endl;
				return false;
			}

			DrawLableText = (DRAWLABLETEXT)GetProcAddress(hDLL, "DrawLableText");
			if (!DrawLableText)
			{
				std::cout << "get DrawLableText API error!" << std::endl;
				return false;
			}

			DrawLableBarCode = (DRAWLABLEBARCODE)GetProcAddress(hDLL, "DrawLableBarCode");
			if (!DrawLableBarCode)
			{
				std::cout << "get DrawLableBarCode API error!" << std::endl;
				return false;
			}

			DrawLableQrCode = (DRAWLABLEQRCODE)GetProcAddress(hDLL, "DrawLableQrCode");
			if (!DrawLableQrCode)
			{
				std::cout << "get DrawLableQrCode API error!" << std::endl;
				return false;
			}

			DrawLableLine = (DRAWLABLELINE)GetProcAddress(hDLL, "DrawLableLine");
			if (!DrawLableLine)
			{
				std::cout << "get DrawLableLine API error!" << std::endl;
				return false;
			}

			DrawLableGraph = (DRAWLABLEGRAPH)GetProcAddress(hDLL, "DrawLableGraph");
			if (!DrawLableGraph)
			{
				std::cout << "get DrawLableGraph API error!" << std::endl;
				return false;
			}

			DrawLableImage = (DRAWLABLEIMAGE)GetProcAddress(hDLL, "DrawLableImage");
			if (!DrawLableImage)
			{
				std::cout << "get DrawLableImage API error!" << std::endl;
				return false;
			}

			FreeBuffer = (FREEBUFFER)GetProcAddress(hDLL, "FreeBuffer");
			if (!FreeBuffer)
			{
				std::cout << "get FreeBuffer API error!" << std::endl;
				return false;
			}

			GeneratePrintPreviewImage = (GENERATEPRINTPREVIEWIMAGE)GetProcAddress(hDLL, "GeneratePrintPreviewImage");
			if (!GeneratePrintPreviewImage)
			{
				std::cout << "get GeneratePrintPreviewImage API error!" << std::endl;
				return false;
			}

			getAllPrinters = (GETALLPRINTERS)GetProcAddress(hDLL, "getAllPrinters");
			if (!getAllPrinters)
			{
				std::cout << "get getAllPrinters API error!" << std::endl;
				return false;
			}

			startJob = (STARJOB)GetProcAddress(hDLL, "startJob");
			if (!startJob)
			{
				std::cout << "get startJob API error!" << std::endl;
				return false;
			}

			startJob_New = (STARTJOB_NEW)GetProcAddress(hDLL, "startJob_New");
			if (!startJob_New)
			{
				std::cout << "get startJob_New API error!" << std::endl;
				return false;
			}

			commitJob = (COMMITJOB)GetProcAddress(hDLL, "commitJob");
			if (!commitJob)
			{
				std::cout << "get commitJob API error!" << std::endl;
				return false;
			}

			picturePrint = (PICTUREPRINT)GetProcAddress(hDLL, "picturePrint");
			if (!picturePrint)
			{
				std::cout << "get picturePrint API error!" << std::endl;
				return false;
			}

			endJob = (ENDJOB)GetProcAddress(hDLL, "endJob");
			if (!endJob)
			{
				std::cout << "get endJob API error!" << std::endl;
				return false;
			}

			initSdk = (INITSDK)GetProcAddress(hDLL, "initSdk");

			if (!initSdk)
			{
				std::cout << "get initSdk API error!" << std::endl;
				return false;
			}

			unInitSdk = (UNINITSDK)GetProcAddress(hDLL, "unInitSdk");
			if (!unInitSdk)
			{
				std::cout << "get unInitSdk API error!" << std::endl;
				return false;
			}

			selectPrinter = (SELECTPRINTER)GetProcAddress(hDLL, "selectPrinter");
			if (!selectPrinter)
			{
				std::cout << "get selectPrinter API error!" << std::endl;
				return false;
			}

			disconnectPrinter = (DISCONNECTPRINTER)GetProcAddress(hDLL, "disconnectPrinter");
			if (!disconnectPrinter)
			{
				std::cout << "get disconnectPrinter API error!" << std::endl;
				return false;
			}

			getPrintLastError = (GETPRINTLASTERROR)GetProcAddress(hDLL, "getPrintLastError");
			if (!getPrintLastError)
			{
				std::cout << "get getPrintLastError API error!" << std::endl;
				return false;
			}

			isConnected = (ISCONNECTED)GetProcAddress(hDLL, "isConnected");
			if (!isConnected)
			{
				std::cout << "get isConnected API error!" << std::endl;
				return false;
			}

			scanWifiPrinter = (SCANWIFIPRINTER)GetProcAddress(hDLL, "scanWifiPrinter");
			if (!scanWifiPrinter)
			{
				std::cout << "get scanWifiPrinter API error!" << std::endl;
				return false;
			}

			connectWifiPrinter = (CONNECTWIFIPRINTER)GetProcAddress(hDLL, "connectWifiPrinter");
			if (!connectWifiPrinter)
			{
				std::cout << "get connectWifiPrinter API error!" << std::endl;
				return false;
			}

			configurationWifi = (CONFIGURATIONWIFI)GetProcAddress(hDLL, "configurationWifi");
			if (!configurationWifi)
			{
				std::cout << "get configurationWifi API error!" << std::endl;
				return false;
			}

			getPaperInfo = (GETPAPERINFO)GetProcAddress(hDLL, "getPaperInfo");
			if (!getPaperInfo)
			{
				std::cout << "get getPaperInfo API error!" << std::endl;
				return false;
			}

			DrawLableQrCodeWithImage = (DRAWLABLEQRCODEWITHIMAGE)GetProcAddress(hDLL, "DrawLableQrCodeWithImage");
			if (!DrawLableQrCodeWithImage)
			{
				std::cout << "get DrawLableQrCodeWithImage API error!" << std::endl;
				return false;
			}
		}
		else
		{
			std::cout << "load jcPrintSdkApi dll error:" << error_id << std::endl;
			return false;
		}

		return true;
	}

	bool freePrinterApiDll()
	{
		if (hDLL)
		{
			FreeLibrary(hDLL);
			hDLL == NULL;
		}

		return true;
	}
}
#endif // JCPRINTERAPI_H_H_H_H
